<?php
require_once "common.inc.php";
set_time_limit(3600);

echo "
<h1><a href='crawler.php'>Lez&aacute;k - crawler</a></h1>
<a href='./'>web</a>
<form action='?'>
<p>New caches from:<br>
<select name='cachers[]' multiple size='10'>
<option value='' selected>---

";
foreach(getCachers() as $cacher_id=>$cacher)
	echo "<option value='$cacher_id'>$cacher";
echo "
</select>
<p><input type='checkbox' name='details'> fetch details (if local copy exist, dont fetch it)
<p><input type='checkbox' name='force_remote'> force remote fetch 

<p><input type='submit'>
</form>
<br><br>
";


if($_REQUEST['cachers']){ 	//download all founds by all cachers
	foreach(getCachers() as $cacher_id=>$cacher){
		if(in_array($cacher_id,  $_REQUEST['cachers'])){
			echo "<h3>For $cacher</h3>";
			$cachesOnline = array();
			fetchPage($cacher_id); //recursion
			
			$cachesIndtb = dibi::query("select waypoint from logs join caches using(cache_id) where cacher_id=$cacher_id and type='smile'")->fetchPairs(); 
			
			if(abs(count($cachesIndtb) - count($cachesOnline)) < 10){
				echo "navic v na webu:"; print_r( array_diff($cachesOnline, $cachesIndtb));
				echo "smazano na webu:"; print_r( array_diff( $cachesIndtb, $cachesOnline)); 
			}
		}
	}
}

if($_REQUEST['details']){
	fetchDetails();
}

exit;




function fetchDetails(){
	$errors = array();

	$total = dibi::fetchSingle("SELECT count(DISTINCT cache_id) FROM logs LEFT JOIN caches USING(cache_id) WHERE luid is NULL");
	$i = 1;
	foreach(dibi::query("SELECT DISTINCT cache_id, uid, waypoint, name FROM logs LEFT JOIN caches USING(cache_id) WHERE luid is NULL") as $cache){
		$cachefile = "cache/".$cache['waypoint'].".htm";
		$local = file_exists($cachefile);
		if($_GET['force_remote'])
			$local = false;
		
		echo "($i/$total) ";
		echo $local ? 'Local' : 'Fetching';
		echo " <a href='http://coord.info/$cache[waypoint]'>$cache[waypoint]</a> $cache[name]...";
		flush(); ob_flush();
		
		if($local)
			$response = file_get_contents($cachefile);
		else {
			$response = curl_getpage("http://www.geocaching.com/seek/cache_details.aspx?wp=".$cache['waypoint']."&log=y&decrypt=");
			file_put_contents($cachefile, $response);
		}
		
		if(!$response) die("error, content missing!");
		
		
		//parse cache details
		$data = array("cache_id"=>$cache['cache_id'], "uid"=>$cache['uid'], "waypoint"=>$cache['waypoint']);
		
		preg_match('~<span id="(?:ctl00_ContentBody_)?CacheName">(.*)</span>~isU', $response, $reg);
		$data["name"] = $reg[1];
		
		preg_match('~WptTypes/[^.]+\.gif" alt="(.*)"~isU', $response, $reg);
		$data["cache_type"] = $reg[1];
	
		preg_match('~alt="Size: ([^"]*)"~isU', $response, $reg);
		$data["size"] = $reg[1];
	
		preg_match('~Difficulty:</strong>[^<]*<img src=".*" alt="(.*) out of 5~isU', $response, $reg);
		$data["stars"] = $reg[1]."/";
	
		preg_match('~Terrain:</strong>[^<]*<img src=".*" alt="(.*) out of 5~isU', $response, $reg);
		$data["stars"] .= $reg[1];
		
		preg_match('~by <a href="http://www\.geocaching\.com/profile/\?guid=[^>]+>([^>]+)</a>~isU', $response, $reg);
		$data["owner"] = $reg[1];	
	
		if(!preg_match('~cdpf\.aspx\?guid=([^$"]+)&amp;lc=5~isU', $response, $reg)) continue;
		$data["uid"] = $reg[1];
		
		if(!$data["name"] OR !$data["cache_type"] OR !$data["size"] OR strlen($data["stars"])<2 OR !$data["owner"]){
			echo'<br>error parsed data!<br>';
			print_r($data);
			continue;
		}
			
		
		dibi::query("REPLACE INTO caches", $data);
		
		//odstranime bez luidu
		//dibi::query("DELETE FROM logs WHERE cache_id='$cache[cache_id]' AND luid IS NULL");


		//parse all logs
		preg_match_all('~<strong><img src="http://www\.geocaching\.com/images/icons/icon_([^.]*).gif"[^>]*>'
			.'&nbsp;([^<]*) by <a[^>]*>('.implode('|', getCachers()).')</a>'
			.'</strong> \(.* found\)<br />(.*)<br /><br /><small><a href=".*LUID=([^"]*)"'
			.'~isU',
		 $response, $match, PREG_SET_ORDER);	

		foreach($match as $r){
			$cacher_id = array_search($r[3], getCachers());
			if($cacher_id !== false){
				
				if($r[1] == 'attended' OR $r[1] == 'camera') $r[1] = 'smile';

				
				$data = array(
					"cacher_id" => $cacher_id,
					"cache_id" => $cache['cache_id'],
					"type" => $r[1],
				);
				
				//idcko
				$id = dibi::fetchSingle("SELECT id FROM logs WHERE %and",$data," AND luid is null");
				if($id)
					$data["id"] = $id;
				
				$data += array(
					"date" => date("Y-m-d", strtotime($r[2])),
					"text" => $r[4],
					"luid" => $r[5],
				);
				
				if($id)
					dibi::query("UPDATE logs SET", $data," WHERE id=%i",$id);
				else
					dibi::query("REPLACE INTO logs", $data);
			}
		}
		
		echo "<a href='./?wp=$cache[waypoint]'>ok</a><!--  ".str_repeat("lorem ipsum", 2)." --><br>";
		flush();
		ob_flush();
		if(!$local)
			sleep(2);
		$i++;
	}
}


function fetchPage($cacher_id, $viewstate=false,$page=1){
	$firsturl = "http://www.geocaching.com/seek/nearest.aspx?ul=".urlencode(getCacher($cacher_id));
	if($viewstate){
		$post = array(
			"__EVENTTARGET" => 'ctl00$ContentBody$pgrTop$ctl08', //'ctl00$ContentBody$pgrTop$lbGoToPage_'.$page,
			"__EVENTARGUMENT" => "",
			"__VIEWSTATE" => $viewstate,
		);
	}
	echo "Getting page $page ...";
	flush(); ob_flush();
	$response = curl_getpage($firsturl, $post ? $post : false);

	//parse viewstate
	preg_match('~<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="(.*)"~isU', $response, $match);
	$viewstate = trim(ereg_replace("\n| |\r", '', $match[1]));
	
	//parse total records
	preg_match('~Total Records: <b>([0-9]*)</b>~isU', $response, $match);
	$total_records = intval($match[1]);
	
	//parse all logs on the page, then iterate through $matches
	preg_match_all('~<a href="/seek/cache_details\.aspx\?guid=(.*)">(.*)</a>.*\((GC.*)\)~isU', $response, $matches, PREG_SET_ORDER);
							//echo "<!-- ".strreplace('-->','__>', print_r(array('viewstate'=>$viewstate, 'm'=>$matches),1))." -->";
	
	$logs = 0;
	global $cachesOnline;
	foreach($matches as $r){
		$data = array("name"=>$r[2], "waypoint"=>$r[3], "uid"=>$r[1]);
		
		//getting cache_id
		$cache_id = dibi::fetchSingle("SELECT cache_id FROM caches WHERE waypoint=%s", $data['waypoint']);
		if(!$cache_id){
			dibi::query("INSERT INTO caches", $data);
			$cache_id = dibi::insertId();
		}
		
		//log exists?
		$log_exists = dibi::fetchSingle("SELECT 1 FROM logs WHERE cache_id=%i", $cache_id, " AND cacher_id=%i",$cacher_id, " AND type='smile'");
		if(!$log_exists){
			dibi::query("INSERT INTO logs", array("cacher_id"=>$cacher_id, "cache_id"=>$cache_id, "type"=>'smile', "luid"=>NULL));
			echo " +"; //<span title='$data[waypoint]'>
		}
		else
			echo " o";
		
		$logs++;
		$cachesOnline[] = $data['waypoint'];
	}
	
	
	//print stats and rerun this function
	$records = dibi::fetchSingle("SELECT count(1) FROM logs WHERE cacher_id=%i",$cacher_id," AND type='smile'");
	if($logs AND $total_records > $records){
		echo "&nbsp; <b>OK</b> (".htmlspecialchars("$records / $total_records").")<br>";
		
		fetchPage($cacher_id, $viewstate, $page+1);
	}
	else
		echo "<br>&nbsp; <b>finish</b> (".htmlspecialchars("$records / $total_records").")<br>";
		flush(); ob_flush();	
}







	
	
